#include "NES_Palette.h"
#include <cstring>
#include <math.h>




static const unsigned char NESPalette_Default[]={
  0x75,0x75,0x75,0x27,0x1B,0x8F,0x00,0x00,0xAB,0x47,0x00,0x9F,0x8F,0x00,0x77,0xAB,0x00,0x13,0xA7,0x00,0x00,0x7F,0x0B,0x00,0x43,0x2F,0x00,0x00,0x47,0x00,0x00,0x51,0x00,0x00,0x3F,0x17,0x1B,0x3F,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xBC,0xBC,0xBC,0x00,0x73,0xEF,0x23,0x3B,0xEF,0x83,0x00,0xF3,0xBF,0x00,0xBF,0xE7,0x00,0x5B,0xDB,0x2B,0x00,0xCB,0x4F,0x0F,0x8B,0x73,0x00,0x00,0x97,0x00,0x00,0xAB,0x00,0x00,0x93,0x3B,0x00,0x83,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0x3F,0xBF,0xFF,0x5F,0x97,0xFF,0xA7,0x8B,0xFD,0xF7,0x7B,0xFF,0xFF,0x77,0xB7,0xFF,0x77,0x63,0xFF,0x9B,0x3B,0xF3,0xBF,0x3F,0x83,0xD3,0x13,0x4F,0xDF,0x4B,0x58,0xF8,0x98,0x00,0xEB,0xDB,0x67,0x67,0x67,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0xAB,0xE7,0xFF,0xC7,0xD7,0xFF,0xD7,0xCB,0xFF,0xFF,0xC7,0xFF,0xFF,0xC7,0xDB,0xFF,0xBF,0xB3,0xFF,0xDB,0xAB,0xFF,0xE7,0xA3,0xE3,0xFF,0xA3,0xAB,0xF3,0xBF,0xB3,0xFF,0xCF,0x9F,0xFF,0xF3,0xA0,0xA2,0xA0,0x00,0x00,0x00,0x00,0x00,0x00
};

static const unsigned char NESPalette_2C02[]={
  0x54,0x54,0x54,0x00,0x1E,0x74,0x08,0x10,0x90,0x30,0x00,0x88,0x44,0x00,0x64,0x5C,0x00,0x30,0x54,0x04,0x00,0x3C,0x18,0x00,0x20,0x2A,0x00,0x08,0x3A,0x00,0x00,0x40,0x00,0x00,0x3C,0x00,0x00,0x32,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x98,0x96,0x98,0x08,0x4C,0xC4,0x30,0x32,0xEC,0x5C,0x1E,0xE4,0x88,0x14,0xB0,0xA0,0x14,0x64,0x98,0x22,0x20,0x78,0x3C,0x00,0x54,0x5A,0x00,0x28,0x72,0x00,0x08,0x7C,0x00,0x00,0x76,0x28,0x00,0x66,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xEC,0xEE,0xEC,0x4C,0x9A,0xEC,0x78,0x7C,0xEC,0xB0,0x62,0xEC,0xE4,0x54,0xEC,0xEC,0x58,0xB4,0xEC,0x6A,0x64,0xD4,0x88,0x20,0xA0,0xAA,0x00,0x74,0xC4,0x00,0x4C,0xD0,0x20,0x38,0xCC,0x6C,0x38,0xB4,0xCC,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,
  0xEC,0xEE,0xEC,0xA8,0xCC,0xEC,0xBC,0xBC,0xEC,0xD4,0xB2,0xEC,0xEC,0xAE,0xEC,0xEC,0xAE,0xD4,0xEC,0xB4,0xB0,0xE4,0xC4,0x90,0xCC,0xD2,0x78,0xB4,0xDE,0x78,0xA8,0xE2,0x90,0x98,0xE2,0xB4,0xA0,0xD6,0xE4,0xA0,0xA2,0xA0,0x00,0x00,0x00,0x00,0x00,0x00
};

static const unsigned char NESPalette_2C03_2C05[]={
  0x60,0x60,0x60,0x00,0x20,0x80,0x00,0x00,0xC0,0x60,0x40,0xC0,0x80,0x00,0x60,0xA0,0x00,0x60,0xA0,0x20,0x00,0x80,0x40,0x00,0x60,0x40,0x00,0x20,0x40,0x00,0x00,0x60,0x20,0x00,0x80,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xA0,0xA0,0xA0,0x00,0x60,0xC0,0x00,0x40,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xE0,0xE0,0x00,0x80,0xE0,0x00,0x00,0xC0,0x60,0x00,0x80,0x60,0x00,0x20,0x80,0x00,0x00,0x80,0x00,0x00,0xA0,0x60,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xE0,0xE0,0xE0,0x60,0xA0,0xE0,0x80,0x80,0xE0,0xC0,0x60,0xE0,0xE0,0x00,0xE0,0xE0,0x60,0xE0,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xC0,0xC0,0x00,0x60,0xC0,0x00,0x00,0xE0,0x00,0x40,0xE0,0xC0,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xE0,0xE0,0xE0,0xA0,0xC0,0xE0,0xC0,0xA0,0xE0,0xE0,0xA0,0xE0,0xE0,0x80,0xE0,0xE0,0xA0,0xA0,0xE0,0xC0,0x80,0xE0,0xE0,0x40,0xE0,0xE0,0x60,0xA0,0xE0,0x40,0x80,0xE0,0x60,0x40,0xE0,0xC0,0x80,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

static const unsigned char NESPalette_RC2C03B[]={
  0x60,0x60,0x60,0x00,0x20,0x80,0x00,0x00,0xC0,0x60,0x40,0xC0,0x80,0x00,0x60,0xA0,0x00,0x60,0xA0,0x20,0x00,0x80,0x40,0x00,0x60,0x40,0x00,0x20,0x00,0x00,0x00,0x60,0x20,0x00,0x80,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xA0,0xA0,0xA0,0x00,0x20,0xC0,0x00,0x40,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xE0,0xE0,0x00,0x80,0xE0,0x00,0x00,0xC0,0x60,0x00,0x80,0x60,0x00,0x20,0x80,0x00,0x00,0x80,0x00,0x00,0xA0,0x60,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xE0,0xE0,0xE0,0x60,0xA0,0xE0,0x80,0x80,0xE0,0xC0,0x60,0xE0,0xE0,0x00,0xE0,0xE0,0x20,0xE0,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xC0,0xC0,0x00,0x60,0x80,0x00,0x00,0xE0,0x00,0x40,0xE0,0xC0,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xE0,0xE0,0xE0,0xA0,0x80,0xE0,0xC0,0xA0,0xE0,0xE0,0xA0,0xE0,0xE0,0x80,0xE0,0xE0,0xA0,0xA0,0xE0,0xC0,0x80,0xE0,0xE0,0x40,0xE0,0xE0,0x60,0xA0,0xA0,0x40,0x80,0xE0,0x60,0x40,0xE0,0xC0,0x80,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

static const unsigned char NESPalette_2C04[]={
  0x60,0x60,0x60,0x00,0x20,0x80,0x00,0x00,0xC0,0x60,0x40,0xC0,0x80,0x00,0x60,0xA0,0x00,0x60,0xA0,0x20,0x00,0x80,0x40,0x00,0x60,0x40,0x00,0x20,0x40,0x00,0x00,0x60,0x20,0x00,0x00,0x00,0x00,0x40,0x40,0x20,0x20,0x20,0x00,0x00,0x60,0x00,0x40,0x00,
  0xA0,0xA0,0xA0,0x00,0x60,0xC0,0x00,0x40,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xE0,0xE0,0x00,0x80,0xE0,0x00,0x00,0xC0,0x60,0x00,0x80,0x60,0x00,0x20,0x80,0x00,0x00,0x80,0x00,0x00,0xA0,0x60,0x00,0x80,0x80,0x40,0x40,0x40,0x40,0x00,0x00,0x60,0x20,0x00,
  0xE0,0xE0,0xE0,0x60,0xA0,0xE0,0x80,0x80,0xE0,0xC0,0x60,0xE0,0xE0,0x00,0xE0,0xE0,0x60,0xE0,0xE0,0x80,0x00,0xE0,0xA0,0x00,0xC0,0xC0,0x00,0x60,0xC0,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
  0xE0,0xE0,0xE0,0xA0,0xC0,0xE0,0xC0,0xA0,0xE0,0xE0,0xA0,0xE0,0xE0,0x80,0xE0,0xE0,0xA0,0xA0,0xE0,0xC0,0x80,0xE0,0xE0,0x40,0xE0,0xE0,0x60,0xA0,0xE0,0x40,0x80,0xE0,0x60,0x40,0xE0,0xC0,0x80,0xC0,0xE0,0xC0,0xC0,0xC0,0xC0,0xA0,0x60,0xE0,0xC0,0x00
};

static const unsigned char NESPalette_RP2C04_0001[]={
  0xE0,0xA0,0xA0,0xC0,0x60,0xE0,0xE0,0x00,0x00,0x80,0x80,0xE0,0x00,0x80,0x80,0x20,0x40,0x00,0x40,0x40,0x40,0xE0,0x00,0x80,0xE0,0xE0,0xE0,0x60,0x60,0x60,0xE0,0xA0,0x00,0xA0,0x00,0x60,0x80,0x00,0x60,0xC0,0xC0,0x00,0x60,0x40,0x00,0xE0,0xE0,0xE0,
  0x60,0xA0,0xE0,0xC0,0xA0,0x60,0x60,0x20,0x00,0x60,0xC0,0x00,0x80,0xC0,0xE0,0xC0,0xA0,0xE0,0xE0,0xC0,0x80,0x00,0x40,0xE0,0xE0,0xC0,0x00,0x40,0xE0,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0xC0,0xC0,0xC0,0x80,0x80,0x80,0xE0,0x00,0xE0,0x00,0x20,0x80,
  0x00,0x00,0x60,0xA0,0xC0,0xE0,0xE0,0xA0,0xE0,0x00,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x40,0x40,0x00,0xA0,0x60,0xA0,0x00,0xE0,0x00,0x00,0x00,0x80,0x40,0x00,0xE0,0x80,0xE0,0xA0,0x20,0x00,0x80,0x00,0xE0,0x00,0x00,0xC0,0xE0,0x80,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x20,0x80,0x00,0xA0,0xA0,0xA0,0x00,0x60,0x20,0xA0,0xE0,0x40,0x60,0x40,0xC0,0xE0,0xE0,0x00,0xC0,0x60,0x00,0x00,0x40,0x00,0x00,0x60,0xC0,0x00,0x80,0x00,0x20,0x20,0x20,0xE0,0xE0,0x60,0xE0,0x60,0xE0,0x80,0x60,0x00,0x80,0xE0,0x60
};

static const unsigned char NESPalette_RP2C04_0002[]={
  0x00,0x00,0x00,0xE0,0xA0,0x00,0x80,0x60,0x00,0xA0,0xE0,0x40,0x80,0xE0,0x60,0xE0,0x60,0xE0,0x00,0x80,0x80,0xA0,0xC0,0xE0,0xE0,0x00,0x00,0x80,0x00,0xE0,0xE0,0xE0,0x60,0xE0,0x80,0xE0,0xE0,0xE0,0xE0,0xC0,0x60,0xE0,0x80,0xC0,0xE0,0x00,0x80,0x00,
  0x00,0x40,0x00,0x60,0xA0,0xE0,0xA0,0x20,0x00,0xC0,0xC0,0xC0,0x00,0xA0,0x60,0x60,0xC0,0x00,0x40,0x00,0x00,0x80,0x80,0xE0,0x40,0x40,0x40,0xE0,0x00,0xE0,0x00,0x00,0x60,0x40,0xE0,0xC0,0xC0,0xA0,0xE0,0x60,0x40,0x00,0x00,0x00,0x00,0x60,0x40,0xC0,
  0x80,0x00,0x60,0xE0,0xC0,0x80,0xE0,0x80,0x00,0xE0,0xA0,0xE0,0x00,0x60,0xC0,0x60,0x20,0x00,0xA0,0xA0,0xA0,0x00,0x00,0xC0,0xA0,0x00,0xE0,0xE0,0xC0,0x00,0x60,0x60,0x60,0x20,0x40,0x00,0x00,0x40,0xE0,0x00,0x00,0x00,0xC0,0xC0,0x00,0xE0,0xE0,0xE0,
  0xC0,0xA0,0x60,0x20,0x20,0x20,0x00,0xE0,0x00,0xC0,0x60,0x00,0x00,0x40,0x40,0x00,0x20,0x80,0xE0,0x00,0x80,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x80,0x40,0x00,0xE0,0xE0,0x00,0xE0,0xA0,0xA0,0xA0,0x00,0x60,0x00,0x60,0x20,0x80,0x80,0x80
};

static const unsigned char NESPalette_RP2C04_0003[]={
  0xA0,0x00,0xE0,0xE0,0x60,0xE0,0x80,0xE0,0x60,0xA0,0xA0,0xA0,0x00,0x80,0x00,0xE0,0xE0,0xE0,0xA0,0xC0,0xE0,0x20,0x40,0x00,0x00,0x20,0x80,0x00,0x00,0x00,0xE0,0xC0,0x80,0x60,0x40,0x00,0xE0,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0xA0,0x60,0x80,0xC0,0xE0,
  0x80,0x80,0xE0,0x00,0x80,0x80,0xA0,0x00,0x60,0x00,0x40,0xE0,0x20,0x80,0x00,0x80,0x60,0x00,0xC0,0x60,0x00,0x00,0xA0,0x60,0x60,0x60,0x60,0x60,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0x00,0x00,0xA0,0x20,0x00,0xE0,0x80,0xE0,0xE0,0xA0,0xA0,
  0xC0,0x60,0xE0,0x00,0x40,0x00,0x00,0x00,0x60,0xE0,0xE0,0x00,0x20,0x20,0x20,0xE0,0xA0,0x00,0xE0,0x80,0x00,0xE0,0xE0,0xE0,0x60,0xC0,0x00,0x80,0x00,0x60,0x60,0xA0,0xE0,0xE0,0x00,0xE0,0x00,0x60,0xC0,0x80,0x80,0x80,0x00,0x00,0x00,0x60,0x20,0x00,
  0x00,0xE0,0xE0,0x40,0x00,0x00,0xA0,0xE0,0x40,0xE0,0xA0,0xE0,0x80,0x40,0x00,0x00,0xE0,0x00,0xC0,0xC0,0x00,0x40,0x40,0x40,0x00,0x60,0x20,0x00,0x00,0x00,0xC0,0xA0,0xE0,0xE0,0xE0,0x60,0x80,0x00,0xE0,0x40,0xE0,0xC0,0xE0,0xC0,0x00,0x00,0x40,0x40
};

static const unsigned char NESPalette_RP2C04_0004[]={
  0x80,0x60,0x00,0x60,0x40,0xC0,0x00,0x80,0x80,0xC0,0xC0,0x00,0x00,0x00,0x00,0xE0,0xA0,0xA0,0x00,0x20,0x80,0xC0,0x60,0x00,0xA0,0xA0,0xA0,0x60,0x20,0x00,0x00,0xE0,0x00,0x00,0x00,0x60,0xE0,0xC0,0x80,0xE0,0xE0,0x00,0x00,0x80,0x00,0xA0,0xE0,0x40,
  0xE0,0x60,0xE0,0x40,0x00,0x00,0x00,0x40,0xE0,0xE0,0x80,0xE0,0x00,0x00,0x00,0x40,0x40,0x40,0xA0,0x20,0x00,0xE0,0x80,0x00,0xC0,0xA0,0x60,0x00,0xA0,0x60,0x80,0x80,0xE0,0x20,0x80,0x00,0x80,0x00,0x60,0x00,0x00,0x00,0x80,0xE0,0x60,0x60,0xA0,0xE0,
  0xA0,0x00,0x60,0x00,0x60,0x20,0x80,0x40,0x00,0x00,0x00,0xC0,0x80,0x00,0xE0,0xA0,0x00,0xE0,0x60,0x60,0x60,0xE0,0x00,0x80,0x00,0x40,0x40,0xC0,0xC0,0xC0,0x00,0x60,0xC0,0x00,0x40,0x00,0x20,0x20,0x20,0xE0,0xE0,0x60,0x80,0x80,0x80,0xE0,0x00,0xE0,
  0xE0,0xA0,0xE0,0xE0,0xE0,0xE0,0x60,0x40,0x00,0xE0,0x00,0x00,0xE0,0xC0,0x00,0x40,0xE0,0xC0,0xE0,0xE0,0xE0,0x80,0xC0,0xE0,0x00,0x00,0x00,0xE0,0xA0,0x00,0xC0,0x60,0xE0,0xA0,0xC0,0xE0,0x60,0xC0,0x00,0xC0,0xA0,0xE0,0x00,0xE0,0xE0,0x20,0x40,0x00
};




NES_Palette* const NES_Palette::Default=new NES_Palette((unsigned char*)NESPalette_Default);
NES_Palette* const NES_Palette::_2C02=new NES_Palette((unsigned char*)NESPalette_2C02);
NES_Palette* const NES_Palette::_2C03_2C05=new NES_Palette((unsigned char*)NESPalette_2C03_2C05);
NES_Palette* const NES_Palette::RC2C03B=new NES_Palette((unsigned char*)NESPalette_RC2C03B);
NES_Palette* const NES_Palette::_2C04=new NES_Palette((unsigned char*)NESPalette_2C04);
NES_Palette* const NES_Palette::RP2C04_0001=new NES_Palette((unsigned char*)NESPalette_RP2C04_0001);
NES_Palette* const NES_Palette::RP2C04_0002=new NES_Palette((unsigned char*)NESPalette_RP2C04_0002);
NES_Palette* const NES_Palette::RP2C04_0003=new NES_Palette((unsigned char*)NESPalette_RP2C04_0003);
NES_Palette* const NES_Palette::RP2C04_0004=new NES_Palette((unsigned char*)NESPalette_RP2C04_0004);




QList<QRgb> NES_Palette::GetRGBList(){
  int i;

  QList<QRgb> r;

  r.clear();

  for(i=0;i<64;i++){
    r.append(qRgb(this->RGB_Array[i*3],this->RGB_Array[i*3+1],this->RGB_Array[i*3+2]));
  }
  for(i=0;i<(256-64);i++){
    r.append(qRgb(0,0,0));
  }

  return r;
}

void NES_Palette::ConvertFrame(uint32_t* Dst,unsigned char* ColorIndexArray,int Length){
  int i;

  for(i=0;i<Length;i++){
    Dst[i]=RGB32_Array[ColorIndexArray[i]&0x3FU];
  }
}

NES_Palette::NES_Palette(unsigned char* RGB_Array){
  int i;

  this->RGB_Array=new unsigned char[64*3];
  this->RGB32_Array=new unsigned int[64];

  //sRGB To RGB
  // for(i=0;i<64*3;i++){
  //   float s;
  //   float d;

  //   s=(float)RGB_Array[i];

  //   s/=255.0f;
  //   if(s<0.04045){
  //     d=s/12.92f;
  //   }else{
  //     d=powf((s+0.055f)/1.055f,2.4f);
  //   }
  //   d*=255.0f;

  //   this->RGB_Array[i]=(unsigned char)d;
  // }

  memcpy(this->RGB_Array,RGB_Array,64*3);

  for(i=0;i<64;i++){
    RGB32_Array[i]=0xFF000000U|(((uint32_t)this->RGB_Array[i*3])<<16)|(((uint32_t)this->RGB_Array[i*3+1])<<8)|((uint32_t)this->RGB_Array[i*3+2]);
  }

}

NES_Palette::~NES_Palette(){

  delete[] RGB_Array;
  delete[] RGB32_Array;
}



